package com.wxmit.framework.quartz.service.impl;

import cn.hutool.core.lang.Assert;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.wxmit.framework.quartz.exception.TaskException;
import com.wxmit.framework.quartz.mapper.SysJobMapper;
import com.wxmit.framework.quartz.service.ISysJobService;
import com.wxmit.framework.quartz.utils.CronUtils;
import com.wxmit.framework.quartz.utils.SchedulerUtils;
import com.wxmit.framework.quartz.constants.SchedulerConstants;
import com.wxmit.framework.quartz.domain.SysJob;
import com.wxmit.system.base.core.ShushanPage;
import com.wxmit.system.base.core.ShushanServiceImpl;
import org.quartz.JobDataMap;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 定时任务调度Service业务层处理
 * 
 * @author xiong
 * @date 2022-08-11
 */
@Service
public class SysJobServiceImpl extends ShushanServiceImpl<SysJobMapper, SysJob>  implements ISysJobService
{
    @Autowired
    private Scheduler scheduler;

    @Autowired
    private SysJobMapper sysJobMapper;

    /**
     * 项目启动时，初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理（注：不能手动修改数据库ID和任务组名，否则会导致脏数据）
     */
    @PostConstruct
    public void init() throws SchedulerException, TaskException
    {
        scheduler.clear();
        List<SysJob> jobList = list();
        for (SysJob job : jobList)
        {
            SchedulerUtils.createScheduleJob(scheduler, job);
        }
    }

    @Override
    public IPage<SysJob> listPage(ShushanPage<SysJob> page, SysJob searchData) {
        LambdaQueryChainWrapper<SysJob> sysJobLambdaQueryChainWrapper = lambdaQuery();
      //TODO::: 查询参数
        return  sysJobLambdaQueryChainWrapper.page(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object insertJob(SysJob sysJob) throws TaskException, SchedulerException {
        Assert.isTrue(CronUtils.isValid(sysJob.getCronExpression()),"cron表达式不正确!");
        boolean save = save(sysJob);
        if(save){
            SchedulerUtils.createScheduleJob(scheduler, sysJob);
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object updateJobById(SysJob sysJob) throws TaskException, SchedulerException {
        Assert.isTrue(CronUtils.isValid(sysJob.getCronExpression()),"cron表达式不正确!");
        boolean update = updateById(sysJob);
        if(update){
            SchedulerUtils.createScheduleJob(scheduler, sysJob);
        }
        return update;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object removeJobByIds(List<Long> jobIds) throws SchedulerException {
        List<SysJob> sysJobs = listByIds(jobIds);
        boolean remove = removeBatchByIds(jobIds);
        if(remove){
            for (SysJob sysJob : sysJobs) {
                scheduler.deleteJob(SchedulerUtils.getJobKey(sysJob.getJobId(), sysJob.getJobGroup()));
            }
        }
        return remove;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object changeStatus(Long id, String status) throws SchedulerException {
        SysJob sysJob = new SysJob();
        sysJob.setJobId(id);
        sysJob.setStatus(status);
        boolean result = updateById(sysJob);
        if (result) {
            SysJob job = this.getById(id);
            Long jobId = job.getJobId();
            String jobGroup = job.getJobGroup();
            if(SchedulerConstants.Status.NORMAL.getValue().equals(job.getStatus())){
                //恢复正常
                scheduler.resumeJob(SchedulerUtils.getJobKey(jobId, jobGroup));
            }else if(SchedulerConstants.Status.PAUSE.getValue().equals(job.getStatus())){
                //暂停执行
                scheduler.pauseJob(SchedulerUtils.getJobKey(jobId, jobGroup));
            }
        }
        return result;
    }

    @Override
    public void executeOnce(Long id) throws SchedulerException {
        SysJob job = getById(id);
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        // 参数
        JobDataMap dataMap = new JobDataMap();
        dataMap.put(SchedulerConstants.TASK_PROPERTIES, job);
        scheduler.triggerJob(SchedulerUtils.getJobKey(jobId, jobGroup), dataMap);
    }




}